<?php
/**
 * Created by PhpStorm.
 * User: Jan-Home
 * Date: 2018/4/5 0005
 * Time: 18:11
 */

namespace Gitee\GiteeAPI;

use Gitee\Db\Gitee\App;
use Gitee\Helper\CurlRequest;
use Ke\Uri;

/**
 * Class AppAPI
 *
 * @package Gitee\GiteeAPI
 *
 * @property \Gitee\GiteeAPI\OrgAPI  $org
 * @property \Gitee\GiteeAPI\RepoAPI $repo
 */
class AppAPI
{
	
	protected $appName;
	
	/** @var \Gitee\Db\Gitee\App */
	protected $app;
	
	protected $oauthBaseUrl = 'https://gitee.com/oauth/';
	
	/** @var  \Ke\Uri */
	protected $oauthUri;
	
	protected $api = [
		'org'  => [
			'class' => OrgAPI::class,
			'obj'   => null,
		],
		'repo' => [
			'class' => RepoAPI::class,
			'obj'   => null,
		],
	];
	
	public function __construct(string $appName)
	{
		$appName = trim($appName);
		if (empty($appName))
			throw new \Exception('Invalid gitee application name!');
		$this->appName = $appName;
	}
	
	public function app()
	{
		if (!isset($this->app)) {
			$this->app = App::loadByName($this->appName);
			if ($this->app->isNew())
				throw  new \Exception('Gitee application undefined!');
		}
		return $this->app;
	}
	
	public function mkOauthUri($path = '', $query = null)
	{
		if (!isset($this->oauthUri)) {
			$this->oauthUri = new Uri($this->oauthBaseUrl);
		}
		return $this->oauthUri->newUri($path, $query);
	}
	
	/**
	 * 获取Gitee的登录验证链接
	 *
	 * @return \Ke\Uri
	 */
	public function getVerifyUri()
	{
		$app = $this->app();
		return $this->mkOauthUri('authorize', [
			'client_id'     => $app->client_id,
			'redirect_uri'  => $app->login_url,
			'response_type' => 'code',
		]);
	}
	
	public function reqToken(string $code)
	{
		$app = $this->app();
		// https://gitee.com/oauth/token?grant_type=authorization_code&code={code}&client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret}
		$uri = $this->mkOauthUri('token', [
			'grant_type'    => 'authorization_code',
			'code'          => $code,
			'client_id'     => $app->client_id,
			'client_secret' => $app->client_secret,
			'redirect_uri'  => $app->login_url,
		]);
		$resp = CurlRequest::new($uri)->post()->getResponse();
		$resp = trim($resp);
		if (empty($resp))
			return false;
		$json = json_decode($resp, true);
		return $json;
	}
	
	public function __get($key)
	{
		if (isset($this->api[$key])) {
			if (!isset($this->api[$key]['obj'])) {
				$class = $this->api[$key]['class'];
				$this->api[$key]['obj'] = new $class($this);
			}
			return $this->api[$key]['obj'];
		}
	}
}